package com.lightboat.web.controller.crm;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lightboat.common.annotation.Log;
import com.lightboat.common.core.controller.BaseController;
import com.lightboat.common.core.domain.AjaxResult;
import com.lightboat.common.core.domain.entity.SysUser;
import com.lightboat.common.core.page.TableDataInfo;
import com.lightboat.common.enums.BusinessType;
import com.lightboat.common.enums.MsgType;
import com.lightboat.common.exception.ServiceException;
import com.lightboat.common.utils.ChainOrderBy;
import com.lightboat.common.utils.PageUtils;
import com.lightboat.common.utils.SecurityUtils;
import com.lightboat.common.utils.poi.ExcelUtil;
import com.lightboat.system.domain.*;
import com.lightboat.system.domain.request.CrmCustomerQueryRequest;
import com.lightboat.system.domain.request.CrmCustomerRequest;
import com.lightboat.system.domain.request.CrmCustomerSalesmanRequest;
import com.lightboat.system.domain.request.CustomerTopRequest;
import com.lightboat.system.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

/**
 * 客户Controller
 *
 * @author lightboat
 * @date 2025-08-14
 */
@Tag(name = "客户管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/system/customer")
public class CrmCustomerController extends BaseController {

    private final ICrmCustomerService crmCustomerService;
    private final ICrmUserFollowRecordService crmUserFollowRecordService;
    private final ICrmUserFollowRelationService crmUserFollowRelationService;
    private final ICrmOrderService crmOrderService;
    private final ISysUserService sysUserService;

    /**
     * 查询客户列表
     */
    @Operation(summary = "查询客户列表")
    @PreAuthorize("@ss.hasPermi('system:customer:list')")
    @GetMapping("/list")
    public TableDataInfo<CrmCustomer> list(CrmCustomerQueryRequest request) {
        ChainOrderBy<CrmCustomer> chainOrderBy = PageUtils.<CrmCustomer>chainOrderBy();
        if (ObjUtil.isNotEmpty(request.getTypeCode()) && "2".equals(request.getTypeCode())){
            chainOrderBy
                    .orderByAsc("top_status")
                    .orderByDesc( "top_time");
        }
        chainOrderBy
                .orderBy(CrmCustomer::getOrderTime, false)
                .orderBy(CrmCustomer::getCustomerId, false)
                .apply();
        startPage();
        CrmCustomer crmCustomer = BeanUtil.copyProperties(request, CrmCustomer.class);
        crmCustomer.getParams().put("isAllocatedSalesman", request.getIsAllocatedSalesman());
        List<CrmCustomer> list = crmCustomerService.selectCrmCustomerList(crmCustomer);
        clearPage();
       list.forEach(item -> {
           CrmUserFollowRecord followRecord1 = new CrmUserFollowRecord();
           followRecord1.setCustomerId(item.getCustomerId());
           followRecord1.setTypeCode("1");
           followRecord1.setUserId(getUserId());
           CrmUserFollowRecord latestRecord1 = crmUserFollowRecordService.getLatestRecord(followRecord1);
           followRecord1.setTypeCode("2");
           CrmUserFollowRecord latestRecord2 = crmUserFollowRecordService.getLatestRecord(followRecord1);
           item.setFollowRemark1((Opt.ofNullable(latestRecord1).map(CrmUserFollowRecord::getFollowRemark).orElse(null)));
           item.setFollowRemark2((Opt.ofNullable(latestRecord2).map(CrmUserFollowRecord::getFollowRemark).orElse(null)));
           Optional<CrmUserFollowRecord> followRecord = crmUserFollowRecordService.getOneOpt(Wrappers.<CrmUserFollowRecord>query().eq("customer_id", item.getCustomerId()).orderByDesc("usage_end_time").last("limit 1"));
           item.setUsageEndTime((followRecord.map(CrmUserFollowRecord::getUsageEndTime).orElse(null)));
           List<CrmOrder> crmOrders = crmOrderService.list(
                   Wrappers.<CrmOrder>lambdaQuery()
                           .select(CrmOrder::getOrderType, CrmOrder::getCount)
                           .eq(CrmOrder::getCustomerId, item.getCustomerId())
                           .eq(CrmOrder::getIsChildren, 0).groupBy(CrmOrder::getOrderType)
           );
           crmOrders.forEach(item1 -> {
               if (1 == item1.getOrderType()) {
                   item.setSysCount(item1.getCount());
               }
               if (2 == item1.getOrderType()) {
                   item.setReCount(item1.getCount());
               }
           });
       });

        return getDataTable(list);
    }


    /**
     * 保存或更新业务员
     */
    @Operation(summary = "保存或更新业务员")
    @PreAuthorize("@ss.hasPermi('system:customer:salesman')")
    @Log(title = "客户", businessType = BusinessType.UPDATE)
    @PostMapping("/salesman")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult salesman(@RequestBody @Validated CrmCustomerSalesmanRequest request) {

        SysUser sysUser = sysUserService.selectUserById(request.getSalesmanId());
        if (sysUser == null) {
            throw new ServiceException("业务员不存在");
        }
        CrmCustomer crmCustomer = crmCustomerService.getById(request.getCustomerId());

        CrmUserFollowRelation crmUserFollowRelation = new CrmUserFollowRelation();
        crmUserFollowRelation.setUserId(request.getSalesmanId());
        crmUserFollowRelation.setCustomerId(request.getCustomerId());
        crmUserFollowRelation.setDeptId(sysUser.getDeptId());

        LambdaQueryWrapper<CrmUserFollowRelation> wrapper = Wrappers.<CrmUserFollowRelation>lambdaQuery()
                .eq(CrmUserFollowRelation::getCustomerId, request.getCustomerId())
                .last("limit 1");
        CrmUserFollowRelation userFollowRelation = crmUserFollowRelationService.getOne(wrapper);
        if (userFollowRelation != null) {
            crmUserFollowRelation.setId(userFollowRelation.getId());
            crmUserFollowRelationService.updateById(crmUserFollowRelation);
        } else {
            crmUserFollowRelationService.save(crmUserFollowRelation);
        }

        CrmCustomer customer = new CrmCustomer();
        customer.setCustomerId(crmCustomer.getCustomerId());
        customer.setSalesmanId(sysUser.getUserId());
        crmCustomerService.updateById(customer);

        LambdaUpdateWrapper<CrmOrder> updateOrderWrapper = Wrappers.<CrmOrder>lambdaUpdate()
                .eq(CrmOrder::getCustomerId, request.getCustomerId())
                .set(CrmOrder::getSalesmanId, request.getSalesmanId())
                .set(CrmOrder::getSalesmanName, sysUser.getNickName());
        boolean update = crmOrderService.update(updateOrderWrapper);
        if (update) {
            List<CrmOrder> orders = crmOrderService.list(Wrappers.<CrmOrder>lambdaQuery()
                    .select(CrmOrder::getOrderId, CrmOrder::getOrderType, CrmOrder::getOrderNo, CrmOrder::getSalesmanId)
                    .eq(CrmOrder::getIsChildren, 0)
                    .eq(CrmOrder::getCustomerId, request.getCustomerId()));
            if (ObjUtil.isNotEmpty(orders)) {
                Long sendUserId = SecurityUtils.getUserId();
                orders.parallelStream().forEach(crmOrder -> {
                    SysNotice sysNotice = SysNotice.builder()
                            .noticeTitle("客户分配成功")
                            .noticeType("1")
                            .noticeContent(StrUtil.format("客户名称：{},订单编号：{}已分配,请注意跟进！", crmCustomer.getCustomerName(), crmOrder.getOrderNo()))
                            .sendId(sendUserId)
                            .userId(crmOrder.getSalesmanId())
                            .msgType(MsgType.ORDINARY.getValue()).build();
                    SpringUtil.publishEvent(sysNotice);
                });
            }
        }
        return success();
    }

    /**
     * 导出客户列表
     */
    @Operation(summary = "导出客户列表")
    @PreAuthorize("@ss.hasPermi('system:customer:export')")
    @Log(title = "客户", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, CrmCustomerQueryRequest request) {
        CrmCustomer crmCustomer = BeanUtil.copyProperties(request, CrmCustomer.class);
        List<CrmCustomer> list = crmCustomerService.selectCrmCustomerList(crmCustomer);
        ExcelUtil<CrmCustomer> util = new ExcelUtil<CrmCustomer>(CrmCustomer.class);
        util.exportExcel(response, list, "客户数据");
    }

    /**
     * 获取客户详细信息
     */
    @Operation(summary = "获取客户详细信息")
    @PreAuthorize("@ss.hasPermi('system:customer:query')")
    @GetMapping(value = "/{customerId}")
    public AjaxResult getInfo(@PathVariable("customerId") Long customerId) {
        return success(crmCustomerService.selectCrmCustomerByCustomerId(customerId));
    }

    /**
     * 新增客户
     */
    @Operation(summary = "新增客户")
    @PreAuthorize("@ss.hasPermi('system:customer:add')")
    @Log(title = "客户", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CrmCustomerRequest request) {
        CrmCustomer crmCustomer = BeanUtil.copyProperties(request, CrmCustomer.class);
        return toAjax(crmCustomerService.insertCrmCustomer(crmCustomer),crmCustomer);
    }

    /**
     * 修改客户
     */
    @Operation(summary = "修改客户")
    @PreAuthorize("@ss.hasPermi('system:customer:edit')")
    @Log(title = "客户", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CrmCustomerRequest request) {
        CrmCustomer crmCustomer = BeanUtil.copyProperties(request, CrmCustomer.class);
        return toAjax(crmCustomerService.updateCrmCustomer(crmCustomer), crmCustomer);
    }

    /**
     * 客户置顶
     */
    @Operation(summary = "客户置顶")
    @PreAuthorize("@ss.hasPermi('system:customer:top')")
    @Log(title = "客户", businessType = BusinessType.UPDATE)
    @PostMapping("/top")
    public AjaxResult orderTop(@RequestBody @Validated CustomerTopRequest request) {
        return toAjax(crmCustomerService.customerTop(request));
    }

    /**
     * 删除客户
     */
    @Operation(summary = "删除客户")
    @PreAuthorize("@ss.hasPermi('system:customer:remove')")
    @Log(title = "客户", businessType = BusinessType.DELETE)
    @DeleteMapping("/{customerIds}")
    public AjaxResult remove(@PathVariable Long[] customerIds) {
        return toAjax(crmCustomerService.deleteCrmCustomerByCustomerIds(customerIds));
    }
}
